<html>
<head>
<title>the reification SPI in Jena 2</title>
<link href="styles/doc.css" rel="stylesheet" type="text/css">
</head>
<body>

<h1>the reification SPI in Jena 2</h1>

<strong>author:</strong> Chris Dollin
<br><strong>version:</strong> 1.0
<br><strong>date:</strong> 1st May 2003

<h1>1. introduction</h1>

<p>
This document describes the reification SPI, the mechanisms by which
the Graph family supports the Model API reification interface.
</p>

<p>
Graphs handle reification at two levels. First, their reifier supports
requests to reify triples and to search for reifications. The reifier
is responsible for managing the reification information it adds
and removes - the graph is not involved.
</p>

<p>Second, a graph may optionally allow all triples added and removed
through its normal operations (including the bulk update interfaces)
to be monitored by its reifier. If so, all appropriate triples become
the property of the reifier - they are no longer visible through the
graph.
</p>

<p>A graph may also have a reifier that doesn't do any reification.
This is useful for internal graphs that are not exposed as models.
So there are three kinds of <code>Graph</code>:
</p>

<ul>
<li>Graphs that do no reification;
<li>Graphs that only do explicit reficiation;
<li>Graphs that do implicit reification.
</ul>

<h1>2. Graph operations for reification</h1>

<p>The primary reification operation on graphs is to extract their
<code>Reifier</code> instance. Handing reification off to a different class
allows reification to be handled independantly of other Graph issues, eg query
handling, bulk update.

<h2>graph.getReifier() -> Reifier</h2>

Returns the <code>Reifier</code> for this <code>Graph</code>.
Each graph has a single reifier during its lifetime. The reifier object need
not be allocated until the first call of <code>getReifier()</code>.

<h2>add(Triple), delete(Triple)</h2>

These two operations may defer their triples to the graph's reifier using
<code>handledAdd(Triple)</code> and <code>handledDelete(Triple)</code>; see
below for details.

<h1>3. interface Reifier</h1>

Instances of <code>Reifier</code> handle reification requests from their
<code>Graph</code> and from the API level code (issues by the API class
<code>ModelReifier</code>.

<h2>reifier.getHiddenTriples() -> Graph</h2>

The reifier may keep reification triples to itself, coded in some special way,
rather than having them stored in the parent <code>Graph</code>. This method
exposes those triples as another <code>Graph</code>. This is a dynamic graph -
it changes as the underlying reifications change. However, it is read-only;
triples cannot be added to or removed from it.

<p>
<blockquote>
The <code>SimpleReifier</code> implementation currently does not implement a
dynamic graph. This is a bug that will need fixing.
</blockquote>

<h2>reifier.getParentGraph() -> Graph</h2>

Get the <code>Graph</code>
that this reifier serves; the result is never <code>null</code>.
(Thus the observable relationship between graphs and reifiers is 1-1.)

<h2>class AlreadyReifiedException</h2>

This class extends <code>RDFException</code>; it is the exception that may be
thrown by <code>reifyAs</code>.

<h2>reifier.reifyAs( Triple t, Node n ) -> Node</h2>

Record the <code>t</code> as reified in the parent <code>Graph</code> by the
given <code>n</code> and returns <code>n</code>. If <code>n</code> already
reifies a different <code>Triple</code>, throw a
<code>AlreadyReifiedException</code>.

<p>Calling <code>reifyAs(t,n)</code> is like adding the triples:

<ul>
<li><code>n rdf:type ref:Statement</code>
<li><code>n rdf:subject t.getSubject()</code>
<li><code>n rdf:predicate t.getPredicate()</code>
<li><code>n rdf:object t.getObject()</code>
</ul>

to the associated Graph; however, it is intended that it is efficient in both
time and space.

<h2>reifier.hasTriple( Triple t ) -> boolean</h2>

Returns true iff some <code>Node n</code> reifies <code>t</code> in this
<code>Reifier</code>, typically by an unretracted call of
<code>reifyAs(t,n)</code>.

<p>The intended (and actual) use for <code>hasTriple(Triple)</code> is in the
implementation of <code>isReified(Statement)</code> in <code>Model</code>.

<h2>reifier.getTriple( Node n ) -> Triple</h2>

Get the single <code>Triple</code> associated with <code>n</code>, if there is
one. If there isn't, return <code>null</code>.

<p>A node reifies at most one triple. If <code>reifyAs</code>, with its
explicit check, is bypassed, and extra reification triples are asserted into
the parent graph, then <code>getTriple()</code> will simply return
<code>null</code>.


<h2>reifier.allNodes() -> ExtendedIterator</h2>

Returns an (extended) iterator over all the nodes that (still) reifiy
something in this reifier.

<p>This is intended for the implementation of
<code>listReifiedStatements</code> in <code>Model</code>.


<h2>reifier.allNodes( Triple t ) -> ClosableIterator</h2>

Returns an iterator over all the nodes that (still) reify the triple _t_.

<h2>reifier.remove( Node n, Triple t )</h2>

Remove the association between <code>n</code> and the triple<code>t</code>.
Subsequently, <code>hasNode(n)</code> will return false and
<code>getTriple(n)</code> will return <code>null</code>.

<p>
This method is used to implement <code>removeReification(Statement)</code> in
<code>Model</code>.

<h2>reifier.remove( Triple t )</h2>

Remove all the associations between any node <code>n</code>
and <code>t</code>; ie, for all <code>n</code> do <code>remove(n,t)</code>.

<p>This method is used to implement <code>removeAllReifications</code> in
<code>Model</code>.

<h2>handledAdd( Triple t ) -> boolean</h2>

A graph doing reification may choose to monitor the triples being added to
it and have the reifier handle reification triples. In this case, the
graph's <code>add(t)</code> should call <code>handledAdd(t)</code> and only
proceed with its add if the result is <code>false</code>.

<p>A graph that does not use <code>handledAdd()</code> [and
<code>handledDelete()</code>] can only use the explict reification supplied by
its reifier.

<h2>handledRemove( Triple t )</h2>

As for <code>handledAdd(t)</code>, but applied to <code>delete</code>.

<h1>4. SimpleReifier</h1>

<code>SimpleReifier</code> is an implementation of <code>Reifier</code>
suitable for in-memory <code>Graph</code>s built over <code>GraphBase</code>.
It operates in either of two modes: with and without triple interception. With
interception enabled, reification triples fed to (or removed from) its parent
graph are captured using <code>handledAdd()</code> and
<code>handledRemove</code>; otherwise they are ignored and the graph must
store them itself.

<p><code>SimpleReifier</code> keeps a map from nodes to the reification
information about that node. Nodes which have no reification information (most
of them, in the usual case) do not appear in the map at all.

<p>Nodes with partial or excessive reification information are associated with
<code>Fragments</code>. A <code>Fragments</code> for a node <code>n</code>
records separately

<ul>
<li>the <code>S</code>s of all <code>n ref:subject S</code> triples
<li>the <code>P</code>s of all <code>n ref:predicate P</code> triples
<li>the <code>O</code>s of all <code>n ref:subject O</code> triples
<li>the <code>T</code>s of all <code>n ref:type T[Statement]</code> triples
</ul>

If the <code>Fragments</code> becomes <em>singular</em>, ie each of these sets
contains exactly one element, then <code>n</code> represents a reification of
the triple <code>(S, P, O)</code>, and the <code>Fragments</code> object is
replaced by that triple.

<p>(If another reification triple for <code>n</code> arrives, then the triple
is re-exploded into <code>Fragments</code>.)

</body>
</html>
